/*package scala.examples.tcpoly.monad;
// by warren harris

////////////////////////////////////////////////////////////////////////////////

case class KMonad[K] {
  case class M[+A](in: (A=>K)=>K) {
    def >>=[B](f: A=>M[B])              = M[B](k => in(b => f(b) in k))
    def >>[B](f: =>M[B])                = M[B](k => in(b => f in k))
  }
  def unit[A](a:A)                      = M[A](k => k(a))
  def ans(m: M[K]):K                    = m in (a => a)
  def callcc[B](f: (B=>M[B])=>M[B])     = M[B](k => f(a => M[B](d => k(a))) in k)
}

////////////////////////////////////////////////////////////////////////////////

case class SKMonad[S,K](state:S) {
  object KM extends KMonad[K]
  case class M[A](in: S=>KM.M[(A,S)]) {
    def >>=[B](f: A=>M[B])      = M[B](s => in(s) >>= {case (a,s) => f(a) in s})
    def >>[B](f: =>M[B])        = M[B](s => in(s) >>= {case (a,s) => f in s})
  }

  private def lift[A](m: KM.M[A]): M[A] = M[A](s => m >>= (a => KM.unit((a, s))))
  def unit[A](a:A): M[A]        = lift(KM.unit[A](a))
  def ans(m: M[K]):K            = m in state in {case (a, s) => a}

  def callcc[A,B](f: (A=>M[B])=>M[A]):M[A] = {
    M[A](s => 
      KM.M[(A,S)](k => 
        f(a =>
          M[B](s2 => KM.M[(B,S)](k2 => k((a, s2)))))
        in s
        in k))
  }

  // state manipulation:
  def get_state                 = M[S](s => KM.unit[(S,S)]((s, s)))
  def set_state(s:S)            = M[Unit](s2 => KM.unit[(Unit,S)](((), s)))
  def update(f: S=>S):M[Unit]   = M[Unit](s => lift(KM.unit[Unit](())) in f(s))
}

////////////////////////////////////////////////////////////////////////////////

trait CVar[S,K] extends SKMonad[S,K] {
  protected def continue[A]():M[A]

  case class CVar[A](name: String) {
    private var waiters : List[A => M[Unit]] = Nil

    def cwait():M[A] = {
      callcc(exit => {
        waiters = exit::waiters;
        continue()
      })
    }

    def notify(arg:A):M[Unit] = {
      waiters match {
        case exit::rest => {
          waiters = rest;
          exit(arg)
        }
        case Nil => unit(())
      }
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

class ThMonadState[K] {
  type T = ThMonad[K]
  var threads : List[T#M[Unit]] = Nil
}

class ThMonad[K] 
extends SKMonad[ThMonadState[K],K](new ThMonadState[K]) 
with CVar[ThMonadState[K],K]
{
  def fork(m: M[Unit]):M[Unit] = {
    update (s => {state.threads = m::state.threads; s})
  }

  protected def process_threads():M[Unit] = {
    state.threads match {
      case m::rest => {
        state.threads = rest;
        m >> (process_threads())
        unit(()) // XXX without this hack, the above line gets a type error
      }
      case Nil => unit(())
    }
  }

  protected def continue[A]():M[A] = {
    process_threads() >> 
    (continue()) // XXX this doesn't seem to be properly tail recursive (stack overflow)
  }

  override def ans(m: M[K]):K    = (m >> (continue())) in state in {case (a, s) => a}

  /*
  // workaround...
  protected def continue1():Unit = {
    while (true) {process_threads()}
  }

  override def ans(m: M[K]):K    = (m >>= (rv => {continue1(); unit(rv)}))
in state in {case (a, s) => a}
  */
}

////////////////////////////////////////////////////////////////////////////////

object test {
  def main(args: Array[String]) {
    object M1 extends KMonad[int]
    val rv = M1.ans(M1.unit(3) >>= (n => M1.unit(n+n)))
    System.out.println(rv)

    object MyMonad extends ThMonad[Unit]
    // XXX fork takes MyMonad#M[Unit], but this seems to type check anyway...
    val m = MyMonad.fork(MyMonad.unit(1) >>= (i => {System.out.println(i); MyMonad.unit(i+1)}))
    System.out.println(MyMonad.ans(m))
  }
}

*/